#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#define LINE  15  //一共有多少个格子
#define EVERY  600/LINE //每一个格式的边是多少，是总的长
gboolean chPosition();
gint sx=0;
gint sy=0;
gint ex=6;
gint ey=6;
gint barx=0;
gint bary=0;
gint length=2;
gint diameter=EVERY;

GtkWidget *window;

GtkWidget *da;

gint a[LINE][LINE]={2};

gint whead,lhead,m=0,n=0,i,j;

gint headok = 0;

gint randflag=0;

gint over = 0;

gint beforeex,beforeey; //记下食物以前放的位置，吃了，不能再放。

static void destroy(GtkWidget *widget,gpointer data)
{
  gtk_main_quit();
}

void press(GtkWidget *widget,GdkEventKey *event)
{
  for(i=0;i<LINE;i++)
     for(j=0;j<LINE;j++)
     {
       if(a[i][j]==length) { m=i;n=j;}
     }
   if (ex == m &&  ey == n)
   {
     beforeex = ex;
     beforeey = ey;
     headok++;
     length=length+1;   
     //++这个是为了食物可以两边跑+++++++
     if (headok%2 == 0)
       randflag = 1;
     else
       randflag = -1 ;
     //++好像不可以用pow()+++++++++++++
     ex = ((ex *13)%LINE+3*randflag); 
     ey = ((ey *17)%LINE+1*randflag); //这个为了产生随机数的
     if (ex>LINE || ex< 0)
       ex=5 ;
     if (ey>LINE || ey<0)
       ey=6;
     if (a[ex][ey]>0  ) //保证eat的东西不在蛇的身体上。
     {
       for(i=0;i<LINE;i++)
          for(j=0;j<LINE;j++)
          {
             if (a[i][j]==0 &&(beforeex!=i && beforeey!=j))
             {
              ex = i ;
                ey = j ;
                break;
             }
          }
     }
     a[ex][ey] = -1;
   }
  g_print("press: %x\n",event->keyval);  //use debug
  switch(event->keyval)
   {
   case 65361: //左键
     g_print("Rigth\n");  //use debug
     if(m==0) over = 1;
     else {m=m-1;}
     break;
   case 65363: //右键    
     g_print("Left\n");   //use debug
     if(m==LINE-1) over = 1;
     else { m=m+1;}
     break;
   case 65364: //下键
     g_print("Down\n");   //use debug
     if(n==LINE) over = 1;
     else {n=n+1; }
     break; 
   case 65362: //上键  
     g_print("up\n");  //use debug
     if(n==0) over = 1;
     else { n=n-1;}
     break;
   case 32: //空格键
     //g_print("Stop\n");  //use debug
     break;
   case 65293: //回车键
     //g_print("Begin\n"); //use debug
     break;
  default:
     break;
   }
   if (a[m][n]>0)
   {
     over = 1 ;
   }
   if (ex == m &&  ey == n)
   {
     beforeex = ex;
     beforeey = ey;
     headok++;
     length=length+1;   
     //++这个是为了食物可以两边跑+++++++
     if (headok%2 == 0)
       randflag = 1;
     else
       randflag = -1 ;
     //++好像不可以用pow()++++++++++++++++++
     //用除法产生随机数，没有rand()产生的好+++
     ex = ((ex *13)%LINE+3*randflag); 
     ey = ((ey *17)%LINE+1*randflag); //这个为了产生随机数的
     if (ex>LINE || ex< 0)
       ex=5 ;
     if (ey>LINE || ey<0)
       ey=6;
     if (a[ex][ey]>0  ) //保证eat的东西不在蛇的身体上。
     {
       for(i=0;i<LINE;i++)
          for(j=0;j<LINE;j++)
       {
          if (a[i][j]==0 &&(beforeex!=i && beforeey!=j))
          {
             ex = i ;
             ey = j;
             break;
          }
       }
     }
     for(i=0;i<LINE;i++)
       for(j=0;j<LINE;j++)
       {
          if(a[i][j]>0) { a[i][j]++; }
       }
     a[ex][ey] = -1;
   }
// if (single == 0)
// {
     for(i=0;i<LINE;i++)
     {
       for(j=0;j<LINE;j++)
          if (a[i][j]>0) a[i][j]--;
     }
     a[m][n] = length;
// } 
}
gboolean my_expose(GtkWidget *da,GdkEventExpose *event,gpointer data   )
{
   GdkGC *gc1,*gc2,*gc;
   GdkColor color;
   gc1 = gdk_gc_new(da->window);
   color.red = 0;
   color.green = 0;
   color.blue = 0;
  gdk_gc_set_rgb_fg_color(gc1,&color);
   gc2 = gdk_gc_new(da->window);
   color.red = 65535;
   color.green = 0;
   color.blue = 0;
  gdk_gc_set_rgb_fg_color(gc2,&color);
   gc = gc1;
  for(i=0;i<LINE;i++)
   {
     for(j=0;j<LINE;j++)
     {
       if(a[i][j]>0) gdk_draw_rectangle(da->window,gc,TRUE,i*EVERY,j*EVERY,EVERY,EVERY);
     }
   }
   gc = gc2;
  for(i=0;i<LINE;i++)
   {
     for(j=0;j<LINE;j++)
     {
       if(a[i][j]<0)
         gdk_draw_arc(da->window,gc,TRUE,EVERY*i,j*EVERY,diameter,diameter,0,64*360);
     }
   }
  g_object_unref(G_OBJECT(gc1));
  g_object_unref(G_OBJECT(gc2));
   return TRUE;
}
void leave_notify_event(GtkWidget *widget, GdkEventMotion *event)
{
   gint x, y;
  GdkModifierType state;
   GdkRectangle rect;
   if (event->is_hint)
     gdk_window_get_pointer(event->window,&x,&y,&state);
  else{
     x = (gint)event->x;
     y = (gint)event->y;
     state = event->state;
   }
   barx = x;
   rect.x = 0;
   rect.y = 470;
   rect.width = 600;
   rect.height = 30; 
  gdk_window_invalidate_rect(da->window,&rect,FALSE);
}

gboolean inBar() //判断滑块和球相碰的范围
{
   if(m >0 && m < LINE-1)
     return TRUE;
   return FALSE;
}
gboolean chPosition() //球的位置
{
   gint tempx=ex;
   gint tempy=ey;
  //++++这是为了让头碰到墙了，死在当前的界面。+++++++++++++
   if (over == 1)
   {
     return FALSE;
   }
  //+++++++++++++++++++++++++++++++++++++++++++++++++++
// g_print ("press: %d--%d--%d\n",ex, ey, barx ); //use debug
  gdk_window_invalidate_rect(da->window,  NULL,   FALSE);
   return TRUE;
}
int main(int argc, char *argv[])
{
   a[6][6] = -1 ;
  gtk_init(&argc,&argv);
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window),"Snake"); //这个只是给个名字。。。
  gtk_widget_set_events ( GTK_WIDGET(window), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK|GDK_BUTTON_PRESS_MASK );

  g_signal_connect(G_OBJECT(window),"delete_event", G_CALLBACK(gtk_main_quit),NULL);

  g_signal_connect(G_OBJECT(window),"key_press_event", G_CALLBACK(press),NULL);

  gtk_widget_add_events( GTK_WIDGET(window), GDK_KEY_PRESS_MASK |GDK_KEY_RELEASE_MASK|GDK_BUTTON_PRESS_MASK);  

  g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(destroy),NULL);

  gtk_signal_connect(GTK_OBJECT(window),"leave_notify_event",  GTK_SIGNAL_FUNC(leave_notify_event),NULL);

   da = gtk_drawing_area_new();

  gtk_widget_set_size_request(da,600,600);

  gtk_container_add(GTK_CONTAINER(window),da);

  g_signal_connect(da,"expose_event",G_CALLBACK(my_expose),NULL);

  gtk_widget_show_all(window);

  g_timeout_add(10,(GSourceFunc)chPosition,NULL);

  gtk_main();

   return 0;
}
